<?php
/**
 * Created by : PhpStorm
 * @date: 2023/7/30 11:34
 */

namespace ClassLibrary;

/**
 * 网站抓取
 * Class ClGrab
 * @package ClassLibrary
 * @date 2023/7/30 11:34
 */
class ClGrab extends ClBase {

    /**
     * 域名
     * @var string
     * @date 2023/7/30 12:01
     */
    private string $domain = '';

    public function grab(string $page_url) {
        if (empty($this->domain)) {
            $this->domain = 'http://' . ClString::getBetween($page_url, '://', '/', false,);
        }
        $html_file = str_replace($this->domain, '', $page_url);
        if (empty($html_file) || $html_file == '/') {
            $html_file = '/index.html';
        }
        //如果最后一个是/，则替换为.html
        if (substr($html_file, -1, 1) == '/') {
            $html_file = substr($html_file, 0, strlen($html_file) - 1) . '.html';
        }
        //替换
        $html_file = str_replace(['.cshtml'], '.html', $html_file);
        $html_file = $this->getFilePublicPath($html_file);
        if (is_file($html_file)) {
            return true;
        }
        try {
            $content = file_get_contents($page_url);
        } catch (\ErrorException $exception) {
            log_info($exception->getMessage());
            return false;
        }
        //获取所有css
        $css_files = ClString::parseToArray($content, '=', '.css');
        foreach ($css_files as $file) {
            //截取
            $file = substr($file, strpos($file, '/'));
            if (!is_file($this->getFilePublicPath($file))) {
                //写入
                try {
                    ClFile::dirCreate($this->getFilePublicPath($file));
                    log_info('css:', $this->domain . $file);
                    file_put_contents($this->getFilePublicPath($file), file_get_contents($this->domain . $file));
                } catch (\ErrorException $exception) {
                    log_info($exception->getMessage());
                    continue;
                }
            }
        }
        //获取所有js
        $js_files = ClString::parseToArray($content, '=', '.js');
        foreach ($js_files as $file) {
            //截取
            $file = substr($file, strpos($file, '/'));
            if (!is_file($this->getFilePublicPath($file))) {
                try {
                    //写入
                    ClFile::dirCreate($this->getFilePublicPath($file));
                    log_info('js:', $this->domain . $file);
                    file_put_contents($this->getFilePublicPath($file), file_get_contents($this->domain . $file));
                } catch (\ErrorException $exception) {
                    log_info($exception->getMessage());
                    continue;
                }
            }
        }
        //获取所有图片
        $suffix = ['.png', '.jpg', '.gif'];
        foreach ($suffix as $each_suffix) {
            $files = ClString::parseToArray($content, '=', $each_suffix);
            foreach ($files as $file) {
                //截取
                $file = substr($file, strpos($file, '/'));
                if (!is_file($this->getFilePublicPath($file))) {
                    try {
                        //写入
                        ClFile::dirCreate($this->getFilePublicPath($file));
                        log_info('img:', $this->domain . $file);
                        file_put_contents($this->getFilePublicPath($file), file_get_contents($this->domain . $file));
                    } catch (\ErrorException $exception) {
                        log_info($exception->getMessage());
                        continue;
                    }
                }
            }
        }
        //存储
        if (!is_file($html_file)) {
            log_info($html_file);
            //写入
            ClFile::dirCreate($html_file);
            file_put_contents($html_file, $content);
        }
        //获取所有跳转地址
        $urls = ClString::parseToArray($content, 'href', '>');
        foreach ($urls as $url) {
            $url = ClString::getBetween($url, '="', '"', false);
            if (strpos($url, '/') !== 0) {
                continue;
            }
            //循环抓取
            $this->grab($this->domain . $url);
        }
        return true;
    }

    /**
     * 获取文件地址
     * @param $file
     * @return string
     * @date 2023/7/30 12:05
     */
    private function getFilePublicPath($file) {
        return public_path($file);
    }

}